Working with OLE 1 Servers
This section
describes some of the known idiosyncrasies of embedding or linking OLE 1
objects.
As with OLE 2
objects, either the IPersistStorage::InitNewJMGO9D method or the IPersistStorage::Load method must be called to
properly initialize a newly instantiated OLE 1 object before any other OLE
calls are made. The InitNew method should be called to initialize a
newly created object; the Load method should be called for existing
objects. If one of the OleCreate helper functions or the OleLoad function is being used,
these functions make the IPersistStorage call, eliminating the need to
make the call directly. When an OLE 2 container with an OLE 1 embedded or
linked object calls the IDataObject::GetData81EL5_ method or the IDataObject::GetDataHere method, the container can
anticipate support for a smaller set of formats and storage mediums than would
be supported for an OLE 2 object. The following table lists the combinations
that can be supported.
|
Tymed
Formats |
Data
Formats |
|
TYMED_MFPICT |
CF_METAFILEPICT |
|
TYMED_GDI |
CF_BITMAP |
|
TYMED_HGLOBAL |
cfNative,
CF_DIB, and other OLE 1 server formats |
For the
aspect value of DVASPECT_ICON, only TYMED_MFPICT with CF_METAFILEPICT is
supported. The icon returned from the IDataObject::GetData or IDataObject::GetDataHere call will always be the first
icon (index 0) in the executable object application.
Several methods
typically called by containers have unique implementations for OLE 1. The IPersistStorage::IsDirty method is defined to return
S_OK if the object has changed since its last save to persistent storage;
S_FALSE if it has not changed. When an OLE 2 container with an OLE 1 embedded
object calls the IPersistStorage::IsDirty method, the compatibility code
always returns S_OK when the server is running, because there is no way to determine
if the object has in fact changed until the File Close or File Update command
is selected. S_FALSE is returned when the server is not running.
An OLE 2
implementation of IOleObject::IsUpToDate can return either S_OK if the object is
up-to-date, S_FALSE if it is not up-to-date, or OLE_E_UNAVAILABLE if the object
cannot determine whether it is up-to-date. The OLE 1 implementation always
returns either E_NOT_RUNNING, if the object is in the loaded state, or S_FALSE,
if the server is running.
The OLE 1
implementation of the IOleItemContainer::EnumObjects method always
returns OLE_E_NOTSUPPORTED because it is not possible for an OLE 1 server to
enumerate its objects.
The IOleObject::Close method takes a save option
as a parameter that indicates whether the object should be saved before the
close occurs. For OLE 2 objects, there are three possible save options:
OLECLOSE_SAVEIFDIRTY, OLECLOSE_NOSAVE, and OLECLOSE_PROMPTSAVE. The OLE 1
implementation of the IOleObject::Close method treats OLECLOSE_PROMPTSAVE
as equivalent to OLECLOSE_SAVEIFDIRTY, because it is not possible to require an
OLE 1 server to prompt the user.
OLE 2
containers cannot expect an OLE 1 object to activate in-place; all OLE 1
objects support activation in a separate, open window.
OLE 1 servers
do not support linking to their embedded objects. It is up to OLE 2 containers
with OLE 1 embedded objects to prevent a possible link from occurring.
Containers can call the CoIsOle1Class function to determine at Clipboard copy time if
a data selection being copied is an OLE 1 object. If the CoIsOle1Class
function returns TRUE, indicating that the selection is an OLE 1 object, the
container should not offer the Link Source format. Link Source must be
available for a linked object to be created.
OLE 2
containers can store multiple presentations for an OLE 1 object. However, only
the first presentation format is sent to the container when the OLE 1 server
closes. After that, the server is in the process of closing down and cannot
honor requests for any more formats. Therefore, only the first presentation cache
will be updated. The rest will be out of date (perhaps blank) if the object has
changed since the last update.
Because OLE 1
servers do not update the cache for every change to an embedded object until
the user selects the File Update command, an OLE 2 container may not be
obtaining the latest data from the server. By calling the IOleObject::Update method, the container can
obtain the latest object data.
An OLE 1
embedded (not linked) object does not notify its container that its data has
changed until the user chooses File Update or File Close. Therefore, if an OLE
2 container registers for a data-change notification on an OLE 2 object in a
particular format, it should be aware that it will not be notified immediately
when the data changes.
When an OLE 1
object is inserted into a container document and then closed without an update
being invoked, the container document is not saved. Neither are the correct
streams for the object written into storage. Any subsequent loading of the
object by the container will fail. To protect against this, containers can keep
data available after the object closes without updating by implementing the
following:
OleCreate(); \\ to insert the object
OleRun(); \\ if OLERENDER_NONE was
specified
IOleObject::Update(); \\ to get snapshot of data
OleSave();
IOleObject::DoVerb();